//
//  YOperation.m
//  MyProject
//
//  Created by yun on 2018/4/25.
//  Copyright © 2018年 yun. All rights reserved.
//

#import "YOperation.h"
#import <objc/runtime.h>

@interface YOperation ()
/*
 覆盖父类属性，Auto property synthesize 不会自动生成，我们需要手动写
 http://blog.163.com/dong_chen/blog/static/256075014201762352618840/
 */
@property (nonatomic,assign,getter=isExecuting) BOOL executing;
@property (nonatomic,assign,getter=isFinished) BOOL finished;
@property (nonatomic,assign,getter=isCancelled) BOOL cancelled;

@property (nonatomic,strong) NSRecursiveLock *lock;
@property (nonatomic,copy) NSString *arg;


@end


@implementation YOperation

@synthesize executing = _executing;
@synthesize finished = _finished;
@synthesize cancelled = _cancelled;

- (instancetype)initWithArg:(NSString *)arg
{
    self = [super init];
    if (self) {
        _arg = arg;
        _executing = NO;
        _finished = NO;
        _cancelled = NO;
        _lock = [NSRecursiveLock new];
    }
    return self;
}

// 调用顺序start → main(重写后，main不会走)
- (void)start{
    // 保证线程安全
    [_lock lock];
    if ([self isCancelled]) {
        self.finished = YES;
        // 释放资源
        
        return;
    }
    
    self.executing = YES;
    [self performSelector:@selector(startOperation)];
    [_lock unlock];
}

- (void)startOperation{
    static int count = 50;
    while (1) {
        @synchronized (self){
            if (count == 0) {
                break;
            }
            NSLog(@"剩余票数：%d===%@==%@",count,[NSThread currentThread],_arg);
        }
    }
}

// cancel
- (void)cancel {
    [_lock lock];
    if (![self isCancelled]) {
        [super cancel];
        self.cancelled = YES;
        if (self.isExecuting) self.executing = NO;
        if (!self.isFinished) self.finished = YES;
        // 具体任务cancel操作
        
    }
    [_lock unlock];
}

//- (void)done{
//    self.finished = YES;
//    self.executing = NO;
//}

#pragma mark -- 属性

- (BOOL)isFinished {
    return _finished;
}

- (void)setFinished:(BOOL)finished{
    [_lock lock];
    if (_finished != finished) {
        [self willChangeValueForKey:@"isFinished"];
        _finished = finished;
        [self didChangeValueForKey:@"isFinished"];
    }
    [_lock unlock];
}

- (BOOL)isExecuting {
    return _executing;
}

- (void)setExecuting:(BOOL)executing{
    [_lock lock];
    if (_executing != executing) {
        [self willChangeValueForKey:@"isExecuting"];
        _executing = executing;
        [self didChangeValueForKey:@"isExecuting"];
    }
    [_lock unlock];
}

- (BOOL)isCancelled{
    return _cancelled;
}

- (void)setCancelled:(BOOL)cancelled{
    [_lock lock];
    if (_cancelled != cancelled) {
        [self willChangeValueForKey:@"isCancelled"];
        _cancelled = cancelled;
        [self didChangeValueForKey:@"isCancelled"];
    }
    [_lock unlock];
}

- (BOOL)isAsynchronous{
    return YES;
}

@end
